package org.example.config;

import com.alibaba.fastjson.JSON;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.example.annotation.OperationLog;
import org.example.constant.Header;
import org.example.constant.RoleEnum;
import org.example.domain.OperationLogEntity;
import org.example.domain.User;
import org.example.domain.UserToken;
import org.example.domain.response.ResponseResult;
import org.example.services.OperationLogService;
import org.example.services.impl.OperationLogServiceImpl;
import org.example.utils.TokenUtils;
import org.example.utils.ipAddressSearchUtil.IpAddressSearchWebServiceClient;
import org.example.utils.ipAddressSearchUtil.requestUtil.RestTemplateGetCountry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.management.relation.RoleResult;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.Objects;

@Aspect
@Component
public class OperationLogAspect {

    @Autowired
    private OperationLogServiceImpl operationLogService;

    /**
     * 定义切点
     *
     * @Pointcut 注解的所在路径
     */
    @Pointcut("@annotation(org.example.annotation.OperationLog)")
    public void logPointCut() {
    }
//    @Before(value = "logPointCut()")
//    public void before(JoinPoint joinPoint)throws Throwable{
//        System.out.println("调用方法前执行。。。");
//    }
//
//    @After(value = "logPointCut()")
//    public void after(JoinPoint joinPoint)throws Throwable{
//        System.out.println("调用方法后执行。。。");
//    }

    @AfterReturning(value = "logPointCut() && @annotation(logger)", returning = "ret")
    public void saveOperationLog(JoinPoint joinPoint, OperationLog logger, Object ret) throws IOException {
        ResponseResult ret1 = (ResponseResult) ret;
        //若返回的结果不成功，则不记录
        if(!"200".equals(ret1.getCode())) return;

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //创建一个操作日志实体类存放此次操作信息
        OperationLogEntity operationLog = new OperationLogEntity();
        //请求记录
//        if(joinPoint.getArgs() != null){
//            //请求json
//            String args = JSON.toJSONString(joinPoint.getArgs());
//            //请求记录
//            operationLog.setRequest(args);
//        }
        //通过请求头的token获取当前操作的用户信息
        String token = request.getHeader(Header.Token);
        UserToken userToken = null;
        if(StringUtils.hasText(token)){
            userToken = TokenUtils.getUserToken(token);
        }
        if (userToken != null) {
            Integer userId = userToken.getUserId();
            String username = userToken.getUsername();
            String role = userToken.getRole();
            operationLog.setLogUserId(userId);
            operationLog.setLogUserName(username);
            operationLog.setLogUserRole(role);
        }else{
            User user = (User) ret1.getData();
            if(request.getRequestURI().matches("/login/loginByUserName")
                    || request.getRequestURI().matches("/login/loginByMail")
                    && user != null){
                operationLog.setLogUserId(user.getUserId());
                operationLog.setLogUserName(user.getUsername());
                operationLog.setLogUserRole(user.getRole());
            }else if(request.getRequestURI().matches("/login/register")){
                User arg = (User)joinPoint.getArgs()[0];
//                String s = JSON.toJSONString(joinPoint.getArgs());
                operationLog.setLogUserId(arg.getUserId());
                operationLog.setLogUserName(arg.getUsername());
                operationLog.setLogUserRole(RoleEnum.User.getKey());
            }else{
                operationLog.setLogUserId(-1);
                operationLog.setLogUserName("未知");
                operationLog.setLogUserRole("未知");
            }
        }
        //若有返回结果,封装返回信息
//        if (null != ret) {
//            //响应内容
//            operationLog.setResponse(ret.toString());
//        }
        //登录地址
        try {
            operationLog.setCountry(IpAddressSearchWebServiceClient.getCountryByIp(request.getLocalAddr()));
        } catch (Exception e) {
            e.printStackTrace();
            operationLog.setCountry("未知");
        }
//        operationLog.setCountry(RestTemplateGetCountry.getCountryByIpAddress(request.getLocalAddr()));
        //请求方法
        operationLog.setMethod(request.getMethod());
        //操作的url
        operationLog.setUri(request.getRequestURI());
        //操作时间
        operationLog.setTime(new Date());
        //操作信息
        operationLog.setInformation(logger.value());

        //将操作日志写入数据库
//        System.out.println(operationLog);
        operationLogService.saveOperationLog(operationLog);

    }
}
